/*
 * CAudioDevice.h
 *
 *  Created on: 2016年4月13日
 *      Author: terry
 */

#ifndef CAUDIODEVICE_H_
#define CAUDIODEVICE_H_

#include "AudioDevice.h"
#include "Ffmpeg.h"
#include "SDL.h"
#include "TCriticalSection.h"
#include "AVFrameQueue.h"
#include "TimePoint.h"
#include "TEvent.h"

namespace av
{

class CAudioDevice: public AudioDevice
{
public:
	CAudioDevice();
	virtual ~CAudioDevice();

	virtual bool open(int channels, int rate, int fmt);

	virtual void close();

	virtual bool isOpen();

	virtual void write(AVFrame* frame);

	virtual void pause(bool toPause);

	virtual void flush();

	virtual bool isPaused();

	virtual float getVolume();

	virtual int setVolume(float vol);

	virtual bool isMute();

	virtual int setMute(bool muted);

	virtual int64_t getCurTime(int64_t* pClock);

    virtual void setScale(AVRational scale);

    virtual void dropTo(int64_t pts);

    virtual void setLiveMode(bool isLive);

    virtual void setMaxDuration(int duration);


	static void sdlAudioCallback(void* userdata, Uint8* stream, int len);
	void audioCallback(Uint8* stream, int len);

    int mixFrame(AVFrame* pFrame, Uint8* buffer, int size, int vol, bool& consumed);
    int mixFrame(AVFrame* pFrame, int pos, Uint8* buffer, int size, int vol, bool& consumed);
    int mixLastFrame(Uint8* buffer, int size, int vol);

    void saveFrame(AVFrame* pFrame, int pos);
    void clearFrame();

    int resample(AVFrame* inFrame, AVFrame* outFrame);

    int64_t getClock();

    AVFrame*    fetchFrame();

	AVFrame* flushResample();

protected:
    SDL_AudioDeviceID   m_audioDev;
    SDL_AudioSpec       m_audioSpec;
    comn::CriticalSection m_cs;
    AVFrameQueue	m_frameQueue;
    AVFrame*    m_curFrame;
    int         m_framePos;
    bool 	m_playing;

    SwrContext*		m_swrContext;
    AVSampleFormat  m_inFormat;
    AVSampleFormat	m_outFormat;
	int		m_resampleRate;

    int		m_volume;
    bool 	m_muted;

    TimePoint	m_curPoint;
    AVRational  m_scale;
    bool		m_isLive;		/// 是否为实时播放模式 
	bool        m_upSampling;   /// 
    int         m_maxDuration;  /// 实时模式下, 最大缓冲 
    
	int64_t	m_frameCount;

};



} /* namespace av */

#endif /* CAUDIODEVICE_H_ */
